using UnityEngine;
using UnityEngine.EventSystems;

namespace FingerPoint.Android.UI
{
    using FingerPoint.Android.Core;

    public class FPInput : BaseInput
    {
        private GestureEnum currGesture; //当前手势

        private bool hasHand = false; //是否有手

        private Vector2 mousePositionCanvas; //鼠标Canvas位置   【根据 [鼠标位置比例] 相对于当前 Canvas 分辨率的位置】
        #region Override
        protected override void Awake()
        {
            base.Awake();
            Provider.Instance.OnHandMetaFound += OnHandMetaFound;
            Provider.Instance.OnHandMetaProcess += OnHandMetaProcess;
            Provider.Instance.OnHandMetaLost += OnHandMetaLost;
            hasHand = Provider.Instance.handMetaState == Provider.HandMetaState.Found;
            FInput.instance = this;
        }

        protected override void OnDisable()
        {
            base.OnDisable();
            Provider.Instance.OnHandMetaFound -= OnHandMetaFound;
            Provider.Instance.OnHandMetaProcess -= OnHandMetaProcess;
            Provider.Instance.OnHandMetaLost -= OnHandMetaLost;
        }

        public override string compositionString => base.compositionString;

        public override IMECompositionMode imeCompositionMode
        {
            get => base.imeCompositionMode;
            set => base.imeCompositionMode = value;
        }
        public override Vector2 compositionCursorPos
        {
            get => base.compositionCursorPos;
            set => base.compositionCursorPos = value;
        }

        public override bool mousePresent
        {
            get { return true; }
        }

        public override Vector2 mousePosition
        {
            get
            {
                if (hasHand)
                {
                    return mousePositionCanvas;
                }
                return base.mousePosition;
            }
        }

        public override Vector2 mouseScrollDelta => base.mouseScrollDelta;

        public override bool touchSupported => base.touchSupported;
        public override int touchCount => base.touchCount;

        public bool HasHand
        {
            get => hasHand;
        }

        public override Touch GetTouch(int index)
        {
            return default;
        }

        public override float GetAxisRaw(string axisName)
        {
            return 0;
        }

        public override bool GetButtonDown(string buttonName)
        {
            return base.GetButtonDown(buttonName);
        }

        public override bool GetMouseButtonDown(int button)
        {
            if (HasHand)
            {
                return IsPick();
            }
            return base.GetMouseButtonDown(button);
        }

        private bool handFirstLost = false;

        public override bool GetMouseButtonUp(int button)
        {
            if (HasHand)
            {
                return IsDrop();
            }
            else if (handFirstLost)
            {
                handFirstLost = false;
                return true;
            }
            return base.GetMouseButtonUp(button);
        }

        public override bool GetMouseButton(int button)
        {
            if (HasHand)
            {
                return IsPinch();
            }
            return base.GetMouseButton(button);
        }
        #endregion

        #region Callback

        // 检测到手
        private void OnHandMetaFound(HandMeta handMeta)
        {
            hasHand = true;
        }

        // 处理手部信息
        private void OnHandMetaProcess(HandMeta handMeta)
        {
            currGesture = handMeta.gesture;
            mousePositionCanvas = new Vector2(handMeta.cursorX, handMeta.cursorY);
        }

        // 手部丢失
        private void OnHandMetaLost(HandMeta handMeta)
        {
            hasHand = false;
            if (handFirstLost == false)
            {
                handFirstLost = true;
            }
        }
        #endregion

        // 模拟点下
        private bool IsPick()
        {
            return currGesture == GestureEnum.pinch;
        }

        // 模拟松开
        private bool IsDrop()
        {
            return currGesture == GestureEnum.loose
                || currGesture == GestureEnum.dragloose
                || currGesture == GestureEnum.nullGesture;
        }

        // 模拟捏合
        private bool IsPinch()
        {
            return currGesture == GestureEnum.longpinching;
        }
    }

    public class FInput
    {
        internal static FPInput instance;

        public static bool GetFingerPick(int button)
        {
            return instance.GetMouseButtonDown(button);
        }

        public static bool GetFingerDrop(int button)
        {
            return instance.GetMouseButtonUp(button);
        }

        public static bool GetFingerPinch(int button)
        {
            return instance.GetMouseButton(button);
        }

        public static bool handPresent => instance.HasHand;

        public static Vector2 POI()
        {
            return instance.mousePosition;
        }
    }
}
